#include <stdio.h>
#include <stdlib.h>
#include "help.h"
#include <getopt.h>
#include <ctype.h>
#include "lista.h"
#include "validation.h"
#include "constants.h"
#include "errors.h"
#include "parser.h"
#include "utils.h"
#include "bubblesort.h"
#include "shellsort.h"

extern void shellsort(char** words, int arraysize);

void Impresora(void*a) {
	printf("%s\n", (char*) a);
}

int main(int argc, char** argv) {

	int next_option;
	int bubbleAlgorithm = 0; // 1 si esta activo (default)
	int shellAlgorithm = 0; // 1 si esta activo
	int state = 0;
	char** words = NULL;
	int arraysize = 0;
	char* inputFilename = NULL;
	int files_initial_pos = 1;
	FILE* input = NULL;
	FILE* output = stdout;
	int cierreDeArchivo = 0;
	void (*FuncionOrdenamiento)(char** words, int arraysize);
	const char* const short_options = "hVsb";
	const struct option long_options[] = { { "help", 0, NULL, 'h' }, {
			"version", 0, NULL, 'V' }, { "shellsort", 0, NULL, 's' }, {
			"bubblesort", 0, NULL, 'b' }, { NULL, 0, NULL, 0 } };

	do {
		next_option = getopt_long(argc, argv, short_options, long_options,
				NULL);
		switch (next_option) {
		case 'h':
			printHelp(argv[0]);
			exit(0);

		case 'V':
			printVersion();
			exit(0);
		case 's':
			files_initial_pos++;
			shellAlgorithm = 1;
			FuncionOrdenamiento = &shellsort;
			break;
		case 'b':
			files_initial_pos++;
			bubbleAlgorithm = 1;
			FuncionOrdenamiento = &bubblesort;
			break;
	    case '?': //opcion invalida
			printHelp(argv[0]);
			exit(0);
		default:
			break;
		}

	} while (next_option != -1);

	/*Si se ingresaron -s y -b al mismo tiempo*/
	if (bubbleAlgorithm && shellAlgorithm) {
		PrintOnlyOneAlgorithm();
	}

	/*Si se ingreso -s o -b*/
	if (bubbleAlgorithm || shellAlgorithm) {
		Lista* l = ConstruirLista(NULL);
		if (strcmp(argv[files_initial_pos], "-") == 0) {
			input = stdin;
			Parsear(input, l);
		} else {
			int i;
			for (i = 0; i < argc - files_initial_pos; i++) {
				inputFilename = argv[files_initial_pos + i];
				input = fopen(inputFilename, "r");
				if (input == NULL)
					file_error(
							"Error: unable to open input file.\n");
				else {
					Parsear(input, l);
					cierreDeArchivo = fclose(input);
					if (cierreDeArchivo != 0)
						file_error("Error: unable to close file.\n");
				}

			}

		}

		words = ListaAArray(l, &arraysize);
		DestruirLista(l);
		FuncionOrdenamiento(words, arraysize);
		ImprimirResultados(output, words, arraysize);
		DestruirArray(words, arraysize);
	}

	return state;
}
